package hos.mock;

import android.text.TextUtils;
import android.util.Log;

import androidx.annotation.NonNull;

import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.text.SimpleDateFormat;
import java.util.Date;
import java.util.UUID;
import java.util.concurrent.TimeUnit;

import hos.constants.Api;
import hos.demo.App;
import hos.demo.R;
import okhttp3.HttpUrl;
import okhttp3.internal.Util;
import okhttp3.mockwebserver.Dispatcher;
import okhttp3.mockwebserver.MockResponse;
import okhttp3.mockwebserver.MockWebServer;
import okhttp3.mockwebserver.RecordedRequest;
import okio.Buffer;
import okio.BufferedSink;
import okio.Okio;

/**
 * <p>Title: MockDispatcher </p>
 * <p>Description:  </p>
 * <p>Company: www.mapuni.com </p>
 *
 * @author : 蔡俊峰
 * @version : 1.0
 * @date : 2024-04-24 10:26
 */
public class MockDispatcher extends Dispatcher {
    public static void initialize() {
        MockWebServer srv = new MockWebServer();
        srv.setDispatcher(new MockDispatcher());
        new Thread(() -> {
            try {
                srv.start(10086);
            } catch (Exception e) {
                Log.e("日志", "MOCK服务启动失败", e);
            }
        }).start();
    }

    @NonNull
    @Override
    public MockResponse dispatch(@NonNull RecordedRequest request) throws InterruptedException {
        HttpUrl requestUrl = request.getRequestUrl();
        if (requestUrl == null) {
            return new MockResponse().setResponseCode(404);
        }
        String path = requestUrl.encodedPath();
        if (path.length() == 0) {
            return new MockResponse().setResponseCode(404);
        }
        if (TextUtils.equals(path, Api.TEXT)) {
            return getString("Request Success : " + request.getMethod());
        }
        if (TextUtils.equals(path, Api.DELAY)) {
            return getString("Request Success : " + request.getMethod()).setBodyDelay(2, TimeUnit.SECONDS);
        }
        if (TextUtils.equals(path, Api.UPLOAD)) {
            return uploadFile(request);
        }
        if (TextUtils.equals(path, Api.GAME)) {
            return getRawResponse(R.raw.game);
        }
        if (TextUtils.equals(path, Api.DATA)) {
            return getRawResponse(R.raw.data);
        }
        if (TextUtils.equals(path, Api.ARRAY)) {
            return getRawResponse(R.raw.array);
        }
        if (TextUtils.equals(path, Api.USER_INFO)) {
            return getRawResponse(R.raw.user);
        }
        if (TextUtils.equals(path, Api.CONFIG)) {
            return getRawResponse(R.raw.config);
        }
        if (TextUtils.equals(path, Api.Token)) {
            return getString(System.currentTimeMillis() + " " + UUID.randomUUID());
        }
        if (TextUtils.equals(path, Api.REQUEST)) {
            MockResponse mockResponse = new MockResponse();
            mockResponse.headers(request.getHeaders());
            return mockResponse.setBody(request.getBody());
        }
        if (TextUtils.equals(path, Api.TIME)) {
            return getString(new SimpleDateFormat("yyyy-MM-dd HH:mm:ss")
                    .format(new Date())).setBodyDelay(1, TimeUnit.SECONDS);
        }
        return new MockResponse().setResponseCode(404);
    }


    private MockResponse getString(String text) {
        return new MockResponse().setHeader("Content-Type", "text/plain").setBody(text);
    }

    // 将接口上传的文件复制到应用缓存目录
    private MockResponse uploadFile(RecordedRequest req) {
        Buffer source = null;
        BufferedSink sink = null;
        try {
            File file = new File(App.getApp().getCacheDir().getAbsolutePath(), "uploadFile.apk");
            source = req.getBody();
            file.createNewFile();
            sink = Okio.buffer(Okio.sink(file));
            sink.writeAll(source);
        } catch (IOException e) {
            throw new RuntimeException(e);
        } finally {
            if (sink != null) {
                Util.closeQuietly(sink);
            }
            if (source != null) {
                Util.closeQuietly(source);
            }
        }
        return new MockResponse().setHeader("Content-Type", "text/plain").setBody("Upload success");
    }

    private MockResponse getRawResponse(int rawId) {
        return getRawResponse(rawId, 500);
    }

    private MockResponse getRawResponse(int rawId, long delay) {
        InputStream inputStream = App.getApp().getResources().openRawResource(rawId);
        String buf = null;
        try {
            buf = Okio.buffer(Okio.source(inputStream)).readUtf8();
        } catch (IOException e) {
            throw new RuntimeException(e);
        }
        return new MockResponse()
                .setHeader("Content-Type", "application/json; charset=utf-8")
                .setBodyDelay(delay, TimeUnit.MILLISECONDS)
                .setBody(buf);
    }
}
